package com.hsjk.szwj.module.pay.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hsjk.szwj.framework.common.constant.CommonConstant;
import com.hsjk.szwj.framework.common.exception.ServiceException;
import com.hsjk.szwj.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.hsjk.szwj.module.pay.dal.dataobject.config.AbstractMchAppReq;
import com.hsjk.szwj.module.pay.dal.dataobject.config.AbstractReq;
import com.hsjk.szwj.module.pay.dal.dataobject.config.MchAppConfigContext;
import com.hsjk.szwj.module.pay.dal.dataobject.system.MchAppDO;
import com.hsjk.szwj.module.pay.dal.dataobject.system.MchInfoDO;
import com.hsjk.szwj.module.pay.service.ConfigContextQueryService;
import com.hsjk.szwj.module.pay.service.IMchInfoService;
import com.hsjk.szwj.module.pay.service.ValidateService;
import com.hsjk.szwj.module.pay.util.JeepayKit;
import com.hsjk.szwj.module.pay.util.RequestKitBean;

import javax.annotation.Resource;

/**
 * @author chenjiawei
 * @desc
 * @Date 2023/08/20 22:09
 **/
public abstract class PayApiController {
    @Resource
    private ValidateService validateService;
    @Resource
    private ConfigContextQueryService configContextQueryService;
    @Resource
    protected RequestKitBean requestKitBean;
    @Resource
    private IMchInfoService mchInfoService;


    /**
     * 获取请求参数并转换为对象，通用验证
     **/
    protected <T extends AbstractReq> T getRQ(Class<T> cls) {

        T bizRQ = getObject(cls);

        // [1]. 验证通用字段规则
        validateService.validate(bizRQ);

        return bizRQ;
    }


    /**
     * 获取请求参数并转换为对象，商户通用验证
     **/
    protected <T extends AbstractReq> T getRQByWithMchSign(Class<T> cls) {

        //获取请求RQ, and 通用验证
        T bizRQ = getRQ(cls);

        AbstractMchAppReq abstractMchAppRQ = (AbstractMchAppReq) bizRQ;

        //业务校验， 包括： 验签， 商户状态是否可用， 是否支持该支付方式下单等。
        Long mchId = abstractMchAppRQ.getMchId();
        Long appId = abstractMchAppRQ.getAppId();
        String sign = bizRQ.getSign();


        if (ObjectUtil.isNull(mchId) || ObjectUtil.isNull(appId) || ObjectUtil.isNull(sign)) {
            throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "参数有误！");

        }

        MchAppConfigContext mchAppConfigContext =
                configContextQueryService.queryMchInfoAndAppInfo(mchId, appId);

        if (mchAppConfigContext == null) {
            throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "商户或商户应用不存在");
        }

        if (mchAppConfigContext.getMchInfo() == null
                || !CommonConstant.YES.equals(mchAppConfigContext.getMchInfo().getState())) {
            throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "商户信息不存在或商户状态不可用");
        }

        MchAppDO mchApp = mchAppConfigContext.getMchApp();
        if (mchApp == null || !CommonConstant.YES.equals(mchApp.getState())) {
            throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "商户应用不存在或应用状态不可用");
        }
        MchInfoDO mchInfoDO = mchInfoService.getMchInfoById(mchId);
        if (!mchApp.getMchId().equals(mchInfoDO.getId())) {
            throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "参数appId与商户号不匹配");
        }

        // 验签
        String appSecret = mchApp.getAppSecret();

        // 转换为 JSON
        JSONObject bizReqJSON = JSONUtil.parseObj(bizRQ);
        bizReqJSON.remove("sign");
        if (!sign.equalsIgnoreCase(JeepayKit.getSign(bizReqJSON, appSecret))) {
            throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "验签失败");
        }

        return bizRQ;
    }

    /**
     * 获取json格式的请求参数
     **/
    protected JSONObject getReqParamJSON() {
        return requestKitBean.getReqParamJSON();
    }

    /**
     * 获取对象类型
     **/
    protected <T> T getObject(Class<T> clazz) {

        JSONObject params = getReqParamJSON();
        T result = JSONUtil.toBean(params, clazz);
        return result;
    }

    /**
     * 获取客户端ip地址
     **/
    public String getClientIp() {
        return requestKitBean.getClientIp();
    }

}
